use std::sync::Arc;
use tokio::sync::{mpsc, Mutex};
use tokio::io::AsyncWriteExt;
use tokio::net::tcp::OwnedWriteHalf;
use serde::{Serialize, Deserialize};
use tracing::{info, error, debug};
use crate::devices::control::messages::{ControlMsgType, generate_control_message};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ControlEvent {
    pub device_id: String,
    pub msg_type: String,
    pub payload: serde_json::Value,
}

#[derive(Debug, Clone, Serialize)]
pub enum DeviceReply {
    MetaData { device_name: String },
    ClipboardChanged { text: String },
    ClipboardSetAck { sequence: u64 },
    UhidOutput { id: u16, size: u16, data: Vec<u8> },
}

pub struct ControlHandler {
    device_id: String,
    writer: Arc<Mutex<Option<OwnedWriteHalf>>>,
    event_sender: mpsc::Sender<ControlEvent>,
    reply_sender: mpsc::Sender<DeviceReply>,
}

impl ControlHandler {
    pub fn new(
        device_id: String,
        event_sender: mpsc::Sender<ControlEvent>,
        reply_sender: mpsc::Sender<DeviceReply>,
    ) -> Self {
        Self {
            device_id,
            writer: Arc::new(Mutex::new(None)),
            event_sender,
            reply_sender,
        }
    }

    pub async fn set_writer(&self, writer: OwnedWriteHalf) {
        let mut w = self.writer.lock().await;
        *w = Some(writer);
    }

    pub async fn send_control_message(
        &self,
        msg_type: ControlMsgType,
        payload: &serde_json::Value,
    ) -> Result<(), String> {
        let mut writer_guard = self.writer.lock().await;
        
        if let Some(writer) = writer_guard.as_mut() {
            let buf = generate_control_message(msg_type, payload);
            
            writer.write_all(&buf).await
                .map_err(|e| format!("Failed to write control message: {}", e))?;
            
            writer.flush().await
                .map_err(|e| format!("Failed to flush control message: {}", e))?;
            
            debug!("Sent control message {:?} to device {}", msg_type, self.device_id);
            Ok(())
        } else {
            Err("No active connection to device".to_string())
        }
    }

    pub async fn handle_inject_keycode(
        &self,
        action: u8,
        keycode: u32,
        repeat: u32,
        metastate: u32,
    ) -> Result<(), String> {
        let payload = serde_json::json!({
            "action": action,
            "keycode": keycode,
            "repeat": repeat,
            "metastate": metastate,
        });
        
        self.send_control_message(ControlMsgType::InjectKeycode, &payload).await
    }

    pub async fn handle_inject_text(&self, text: String) -> Result<(), String> {
        let payload = serde_json::json!({
            "text": text,
        });
        
        self.send_control_message(ControlMsgType::InjectText, &payload).await
    }

    pub async fn handle_inject_touch(
        &self,
        action: u8,
        pointer_id: u64,
        x: i32,
        y: i32,
        w: u16,
        h: u16,
        pressure: f32,
        action_button: u32,
        buttons: u32,
    ) -> Result<(), String> {
        let payload = serde_json::json!({
            "action": action,
            "pointerId": pointer_id,
            "position": {
                "x": x,
                "y": y,
                "w": w,
                "h": h,
            },
            "pressure": pressure,
            "actionButton": action_button,
            "buttons": buttons,
        });
        
        self.send_control_message(ControlMsgType::InjectTouchEvent, &payload).await
    }

    pub async fn handle_inject_scroll(
        &self,
        x: i32,
        y: i32,
        w: u16,
        h: u16,
        hscroll: f32,
        vscroll: f32,
        buttons: u32,
    ) -> Result<(), String> {
        let payload = serde_json::json!({
            "position": {
                "x": x,
                "y": y,
                "w": w,
                "h": h,
            },
            "hscroll": hscroll,
            "vscroll": vscroll,
            "buttons": buttons,
        });
        
        self.send_control_message(ControlMsgType::InjectScrollEvent, &payload).await
    }

    pub async fn handle_back_or_screen_on(&self, action: u8) -> Result<(), String> {
        let payload = serde_json::json!({
            "action": action,
        });
        
        self.send_control_message(ControlMsgType::BackOrScreenOn, &payload).await
    }

    pub async fn handle_get_clipboard(&self, copy_key: u8) -> Result<(), String> {
        let payload = serde_json::json!({
            "copyKey": copy_key,
        });
        
        self.send_control_message(ControlMsgType::GetClipboard, &payload).await
    }

    pub async fn handle_set_clipboard(
        &self,
        sequence: u64,
        text: String,
        paste: bool,
    ) -> Result<(), String> {
        let payload = serde_json::json!({
            "sequence": sequence,
            "text": text,
            "paste": paste,
        });
        
        self.send_control_message(ControlMsgType::SetClipboard, &payload).await
    }

    pub async fn handle_set_screen_power_mode(&self, mode: u8) -> Result<(), String> {
        let payload = serde_json::json!({
            "mode": mode,
        });
        
        self.send_control_message(ControlMsgType::SetScreenPowerMode, &payload).await
    }

    pub async fn handle_rotate_device(&self) -> Result<(), String> {
        self.send_control_message(ControlMsgType::RotateDevice, &serde_json::json!({})).await
    }

    pub async fn handle_expand_notification_panel(&self) -> Result<(), String> {
        self.send_control_message(ControlMsgType::ExpandNotificationPanel, &serde_json::json!({})).await
    }

    pub async fn handle_expand_settings_panel(&self) -> Result<(), String> {
        self.send_control_message(ControlMsgType::ExpandSettingsPanel, &serde_json::json!({})).await
    }

    pub async fn handle_collapse_panels(&self) -> Result<(), String> {
        self.send_control_message(ControlMsgType::CollapsePanels, &serde_json::json!({})).await
    }
}